package com.inspur.edp.bef.bizentity.json.increment;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.inspur.edp.bef.bizentity.common.BizEntityJsonConst;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityErrorCodeEnum;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityException;
import com.inspur.edp.bef.bizentity.increment.BizObjectIncrement;
import com.inspur.edp.bef.bizentity.increment.entity.determination.DtmIncrement;
import com.inspur.edp.bef.bizentity.increment.entity.validation.ValIncrement;
import com.inspur.edp.bef.bizentity.json.object.BizObjectDeserializer;
import com.inspur.edp.cef.designtime.api.entity.increment.ModifyEntityIncrement;
import com.inspur.edp.cef.designtime.api.json.CefNames;
import com.inspur.edp.das.commonmodel.json.increment.CommonElementIncrementDeserializer;
import com.inspur.edp.das.commonmodel.json.increment.CommonObjectIncrementDeserializer;
import com.inspur.edp.das.commonmodel.json.object.CmObjectDeserializer;

import java.io.IOException;

public class BizObjectIncrementDeserializer extends CommonObjectIncrementDeserializer {
    @Override
    protected CmObjectDeserializer getCommonObjectDeserializer() {
        return new BizObjectDeserializer();
    }

    @Override
    protected CommonElementIncrementDeserializer getCmElementIncrementDeserizlizer() {
        return new BizElementIncrementDeserializer();
    }

    @Override
    protected CommonObjectIncrementDeserializer getCmObjectIncrementDeserializer() {
        return new BizObjectIncrementDeserializer();
    }

    @Override
    protected ModifyEntityIncrement createModifyIncrement(){
        return new BizObjectIncrement();
    }

    @Override
    protected void readExtendModifyInfo(ModifyEntityIncrement value, JsonNode node) {

        BizObjectIncrement increment = (BizObjectIncrement) value;
        JsonNode dtmIncrements = node.get(BizEntityJsonConst.Determinations);
        if (dtmIncrements != null)
            readDeterminations(increment, dtmIncrements);

        JsonNode valIncrements = node.get(BizEntityJsonConst.Validations);
        if (valIncrements != null)
            readValidations(increment, valIncrements);
    }

    private void readDeterminations(BizObjectIncrement increment, JsonNode node) {
        ArrayNode array = trans2Array(node);
        for (JsonNode childNode : array) {
            DtmIncrementDeserializer serializer = new DtmIncrementDeserializer();
            ObjectMapper mapper = new ObjectMapper();
            SimpleModule module = new SimpleModule();
            module.addDeserializer(DtmIncrement.class, serializer);
            mapper.registerModule(module);
            try {
                String key = childNode.get(CefNames.Id).textValue();
                JsonNode valueNode = childNode.get(BizEntityJsonConst.Determination);

                DtmIncrement dtmIncrement = mapper.readValue(mapper.writeValueAsString(valueNode), DtmIncrement.class);
                dtmIncrement.setActionId(key);
                increment.getDeterminations().put(key, dtmIncrement);
            } catch (IOException e) {
                throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_JSON_0001, e, "DtmIncrement");
            }
        }
    }

    private void readValidations(BizObjectIncrement increment, JsonNode node) {
        ArrayNode array = trans2Array(node);
        for (JsonNode childNode : array) {
            ValIncrementDeserializer serializer = new ValIncrementDeserializer();
            ObjectMapper mapper = new ObjectMapper();
            SimpleModule module = new SimpleModule();
            module.addDeserializer(ValIncrement.class, serializer);
            mapper.registerModule(module);
            try {
                String key = childNode.get(CefNames.Id).textValue();
                JsonNode valueNode = childNode.get(BizEntityJsonConst.Validation);

                ValIncrement valIncrement = mapper.readValue(mapper.writeValueAsString(valueNode), ValIncrement.class);
                valIncrement.setActionId(key);
                increment.getValidations().put(key, valIncrement);
            } catch (IOException e) {
                throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_JSON_0001, e, "ValIncrement");
            }
        }
    }

    private ArrayNode trans2Array(JsonNode node) {
        try {
            return new ObjectMapper().treeToValue(node, ArrayNode.class);
        } catch (JsonProcessingException e) {
            throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_JSON_0003, e);
        }
    }
}
